A new view.pdb function based on NGL

Author

Barry

I have experimented with r3dmol and NGLVieweR packages and decided that NGLVieweR is the best option going forward - primarily as r3dmol has no atom-based selection and they have no plans to upgrade to the latest JS library.

library(NGLVieweR)
library(bio3d)

ras <- read.pdb("5p21")
  Note: Accessing on-line PDB file
pdb <- read.pdb("1hsg")
  Note: Accessing on-line PDB file
pc  <- read.pdb("pca.pdb", multi = T)
source("ngl_functions.R")
n <- view.pdb(pdb)
n
view.pdb(ras)
view.pdb(pc)
sele <- atom.select(ras, resno=c(16, 57, 35))
view.pdb(ras, highlight = sele)
NGLVieweR(pdb2ngl(pdb), format="pdb") |>
  addRepresentation("cartoon")
NGLVieweR(pdb2ngl(pc), format="pdb") |>
  addRepresentation("cartoon")

How about an NMA result

adk <- read.pdb("6s36")
  Note: Accessing on-line PDB file
   PDB has ALT records, taking A only, rm.alt=TRUE
view.pdb(adk)
m <- nma(adk)
 Building Hessian...        Done in 0.008 seconds.
 Diagonalizing Hessian...   Done in 0.175 seconds.
a <- mktrj(m, file="nma.pdb")
n <- read.pdb("nma.pdb", multi=T)
view.pdb(n)
#NGLVieweR(b2n(pc), format="pdb") |>
#  addRepresentation("cartoon")
view.pdb(pc)
#data <- "pca.pdb"
#data <- paste(readLines(data), collapse = "\n")
#NGLVieweR(data, format="pdb") |>
#  addRepresentation("cartoon")
#x <- b2n(p)
view.pdb(pdb)
sele <- atom.select(pdb, resno=c(25, 50))

view.pdb(pdb, highlight = sele, 
         chain.colors = c("navy","orange"),
         backgroundColor = "pink",
         highlight.style = "spacefill")
m <- view.pdb(ras)

ras2 <- read.pdb("4q21")
  Note: Accessing on-line PDB file
m |> 
  addStructure(pdb2ngl(ras2), format="pdb") |>
  addRepresentation("cartoon", param = list(color = "orange"))

How about pdbs objects…

pth <- "~/Desktop/courses/BIMM143/class10/pdbs/split_chain/"
files <- list.files(path=pth, full.names = T)
pdbs <- pdbaln(files, fit=T, exefile="msa")
Reading PDB files:
/Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//1AKE_A.pdb
/Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//1E4V_A.pdb
/Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//1E4Y_A.pdb
/Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//3HPR_A.pdb
/Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//3X2S_A.pdb
/Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//4K46_A.pdb
/Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//4NP6_A.pdb
/Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//4X8H_A.pdb
/Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//4X8M_A.pdb
/Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//5EJE_A.pdb
/Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//6HAM_A.pdb
/Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//6HAP_A.pdb
/Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//6RZE_A.pdb
/Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//6S36_A.pdb
/Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//8BQF_A.pdb
/Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//8PVW_A.pdb
/Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//8Q2B_A.pdb
/Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//8RJ9_A.pdb
   PDB has ALT records, taking A only, rm.alt=TRUE
...   PDB has ALT records, taking A only, rm.alt=TRUE
..   PDB has ALT records, taking A only, rm.alt=TRUE
....   PDB has ALT records, taking A only, rm.alt=TRUE
.   PDB has ALT records, taking A only, rm.alt=TRUE
..   PDB has ALT records, taking A only, rm.alt=TRUE
.   PDB has ALT records, taking A only, rm.alt=TRUE
.   PDB has ALT records, taking A only, rm.alt=TRUE
.   PDB has ALT records, taking A only, rm.alt=TRUE
.   PDB has ALT records, taking A only, rm.alt=TRUE
.   PDB has ALT records, taking A only, rm.alt=TRUE
.

Extracting sequences

pdb/seq: 1   name: /Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//1AKE_A.pdb 
   PDB has ALT records, taking A only, rm.alt=TRUE
pdb/seq: 2   name: /Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//1E4V_A.pdb 
pdb/seq: 3   name: /Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//1E4Y_A.pdb 
pdb/seq: 4   name: /Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//3HPR_A.pdb 
   PDB has ALT records, taking A only, rm.alt=TRUE
pdb/seq: 5   name: /Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//3X2S_A.pdb 
pdb/seq: 6   name: /Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//4K46_A.pdb 
   PDB has ALT records, taking A only, rm.alt=TRUE
pdb/seq: 7   name: /Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//4NP6_A.pdb 
pdb/seq: 8   name: /Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//4X8H_A.pdb 
pdb/seq: 9   name: /Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//4X8M_A.pdb 
pdb/seq: 10   name: /Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//5EJE_A.pdb 
   PDB has ALT records, taking A only, rm.alt=TRUE
pdb/seq: 11   name: /Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//6HAM_A.pdb 
   PDB has ALT records, taking A only, rm.alt=TRUE
pdb/seq: 12   name: /Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//6HAP_A.pdb 
pdb/seq: 13   name: /Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//6RZE_A.pdb 
   PDB has ALT records, taking A only, rm.alt=TRUE
pdb/seq: 14   name: /Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//6S36_A.pdb 
   PDB has ALT records, taking A only, rm.alt=TRUE
pdb/seq: 15   name: /Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//8BQF_A.pdb 
   PDB has ALT records, taking A only, rm.alt=TRUE
pdb/seq: 16   name: /Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//8PVW_A.pdb 
   PDB has ALT records, taking A only, rm.alt=TRUE
pdb/seq: 17   name: /Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//8Q2B_A.pdb 
   PDB has ALT records, taking A only, rm.alt=TRUE
pdb/seq: 18   name: /Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//8RJ9_A.pdb 
   PDB has ALT records, taking A only, rm.alt=TRUE

Optional core fitting

core <- core.find(pdbs)
 core size 181 of 182  vol = 183.539 
 core size 180 of 182  vol = 122.485 
 core size 179 of 182  vol = 105.408 
 core size 178 of 182  vol = 93.18 
 core size 177 of 182  vol = 88.906 
 core size 176 of 182  vol = 84.784 
 core size 175 of 182  vol = 80.968 
 core size 174 of 182  vol = 77.53 
 core size 173 of 182  vol = 74.405 
 core size 172 of 182  vol = 71.103 
 core size 171 of 182  vol = 68.141 
 core size 170 of 182  vol = 65.146 
 core size 169 of 182  vol = 62.022 
 core size 168 of 182  vol = 58.823 
 core size 167 of 182  vol = 55.699 
 core size 166 of 182  vol = 52.797 
 core size 165 of 182  vol = 50.476 
 core size 164 of 182  vol = 48.432 
 core size 163 of 182  vol = 46.409 
 core size 162 of 182  vol = 44.266 
 core size 161 of 182  vol = 42.478 
 core size 160 of 182  vol = 40.614 
 core size 159 of 182  vol = 38.531 
 core size 158 of 182  vol = 36.678 
 core size 157 of 182  vol = 34.722 
 core size 156 of 182  vol = 32.664 
 core size 155 of 182  vol = 30.706 
 core size 154 of 182  vol = 28.818 
 core size 153 of 182  vol = 27.099 
 core size 152 of 182  vol = 25.611 
 core size 151 of 182  vol = 24.455 
 core size 150 of 182  vol = 23.337 
 core size 149 of 182  vol = 22.373 
 core size 148 of 182  vol = 21.59 
 core size 147 of 182  vol = 20.732 
 core size 146 of 182  vol = 19.95 
 core size 145 of 182  vol = 19.125 
 core size 144 of 182  vol = 18.232 
 core size 143 of 182  vol = 17.465 
 core size 142 of 182  vol = 16.751 
 core size 141 of 182  vol = 16.304 
 core size 140 of 182  vol = 15.747 
 core size 139 of 182  vol = 15.319 
 core size 138 of 182  vol = 14.793 
 core size 137 of 182  vol = 14.469 
 core size 136 of 182  vol = 14.114 
 core size 135 of 182  vol = 13.656 
 core size 134 of 182  vol = 13.235 
 core size 133 of 182  vol = 12.847 
 core size 132 of 182  vol = 12.587 
 core size 131 of 182  vol = 12.271 
 core size 130 of 182  vol = 11.958 
 core size 129 of 182  vol = 11.682 
 core size 128 of 182  vol = 11.355 
 core size 127 of 182  vol = 11.016 
 core size 126 of 182  vol = 10.612 
 core size 125 of 182  vol = 10.328 
 core size 124 of 182  vol = 10.052 
 core size 123 of 182  vol = 9.767 
 core size 122 of 182  vol = 9.492 
 core size 121 of 182  vol = 9.156 
 core size 120 of 182  vol = 8.834 
 core size 119 of 182  vol = 8.577 
 core size 118 of 182  vol = 8.349 
 core size 117 of 182  vol = 8.093 
 core size 116 of 182  vol = 7.881 
 core size 115 of 182  vol = 7.673 
 core size 114 of 182  vol = 7.441 
 core size 113 of 182  vol = 7.247 
 core size 112 of 182  vol = 7.061 
 core size 111 of 182  vol = 6.899 
 core size 110 of 182  vol = 6.703 
 core size 109 of 182  vol = 6.548 
 core size 108 of 182  vol = 6.371 
 core size 107 of 182  vol = 6.189 
 core size 106 of 182  vol = 6.017 
 core size 105 of 182  vol = 5.874 
 core size 104 of 182  vol = 5.695 
 core size 103 of 182  vol = 5.543 
 core size 102 of 182  vol = 5.403 
 core size 101 of 182  vol = 5.269 
 core size 100 of 182  vol = 5.14 
 core size 99 of 182  vol = 5.034 
 core size 98 of 182  vol = 4.914 
 core size 97 of 182  vol = 4.819 
 core size 96 of 182  vol = 4.695 
 core size 95 of 182  vol = 4.604 
 core size 94 of 182  vol = 4.482 
 core size 93 of 182  vol = 4.362 
 core size 92 of 182  vol = 4.25 
 core size 91 of 182  vol = 4.162 
 core size 90 of 182  vol = 4.061 
 core size 89 of 182  vol = 3.951 
 core size 88 of 182  vol = 3.849 
 core size 87 of 182  vol = 3.748 
 core size 86 of 182  vol = 3.633 
 core size 85 of 182  vol = 3.533 
 core size 84 of 182  vol = 3.457 
 core size 83 of 182  vol = 3.374 
 core size 82 of 182  vol = 3.28 
 core size 81 of 182  vol = 3.18 
 core size 80 of 182  vol = 3.072 
 core size 79 of 182  vol = 2.986 
 core size 78 of 182  vol = 2.909 
 core size 77 of 182  vol = 2.813 
 core size 76 of 182  vol = 2.713 
 core size 75 of 182  vol = 2.636 
 core size 74 of 182  vol = 2.555 
 core size 73 of 182  vol = 2.465 
 core size 72 of 182  vol = 2.399 
 core size 71 of 182  vol = 2.341 
 core size 70 of 182  vol = 2.281 
 core size 69 of 182  vol = 2.2 
 core size 68 of 182  vol = 2.132 
 core size 67 of 182  vol = 2.071 
 core size 66 of 182  vol = 1.982 
 core size 65 of 182  vol = 1.903 
 core size 64 of 182  vol = 1.844 
 core size 63 of 182  vol = 1.788 
 core size 62 of 182  vol = 1.726 
 core size 61 of 182  vol = 1.668 
 core size 60 of 182  vol = 1.613 
 core size 59 of 182  vol = 1.535 
 core size 58 of 182  vol = 1.482 
 core size 57 of 182  vol = 1.423 
 core size 56 of 182  vol = 1.367 
 core size 55 of 182  vol = 1.315 
 core size 54 of 182  vol = 1.262 
 core size 53 of 182  vol = 1.206 
 core size 52 of 182  vol = 1.146 
 core size 51 of 182  vol = 1.094 
 core size 50 of 182  vol = 1.041 
 core size 49 of 182  vol = 0.998 
 core size 48 of 182  vol = 0.935 
 core size 47 of 182  vol = 0.882 
 core size 46 of 182  vol = 0.823 
 core size 45 of 182  vol = 0.752 
 core size 44 of 182  vol = 0.685 
 core size 43 of 182  vol = 0.638 
 core size 42 of 182  vol = 0.589 
 core size 41 of 182  vol = 0.55 
 core size 40 of 182  vol = 0.511 
 core size 39 of 182  vol = 0.473 
 FINISHED: Min vol ( 0.5 ) reached
core.inds <- print(core)
# 50 positions (cumulative volume <= 1 Angstrom^3) 
   start end length
1      1   6      6
2     16  16      1
3     20  21      2
4     25  29      5
5     80  84      5
6     86  87      2
7     93  93      1
8    102 111     10
9    179 186      8
10   188 195      8
11   197 198      2
xyz <- pdbfit(pdbs, core.inds, outpath="corefit_structures")
   PDB has ALT records, taking A only, rm.alt=TRUE
   PDB has ALT records, taking A only, rm.alt=TRUE
   PDB has ALT records, taking A only, rm.alt=TRUE
   PDB has ALT records, taking A only, rm.alt=TRUE
   PDB has ALT records, taking A only, rm.alt=TRUE
   PDB has ALT records, taking A only, rm.alt=TRUE
   PDB has ALT records, taking A only, rm.alt=TRUE
   PDB has ALT records, taking A only, rm.alt=TRUE
   PDB has ALT records, taking A only, rm.alt=TRUE
   PDB has ALT records, taking A only, rm.alt=TRUE
   PDB has ALT records, taking A only, rm.alt=TRUE
pdbs$xyz <- xyz
## Convert back to PDB objects
all.pdbs <- pdbs2pdb(pdbs)
## Access the first PDB object
# all.pdbs[[1]]

mycols <- vmd_colors()
names(mycols) <- NULL

m <- view.pdb(all.pdbs[[1]], backgroundColor = "black")

for(k in 2:length(pdbs$id)) {
  m <- m |>
    addStructure(pdb2ngl(all.pdbs[[k]]), format="pdb") |>
      addRepresentation("line", param = list(color = mycols[k]))
}
m
m <- view.pdb(all.pdbs[[1]], backgroundColor = "black")
m
NGLVieweR(pdb2ngl( all.pdbs[[1]] ), format="pdb") |>
  addRepresentation("cartoon")

PDB code 1crr is a NMR ras structure

# files see above
nfiles <- length(files)
cols <- vmd_colors(nfiles)
names(cols) <- NULL

x <- NGLVieweR(files[1]) |>
  addRepresentation("cartoon", param = list(color = cols[1]))

for(i in 2:nfiles) {
  cat(files[i],"\n")
  x <- x |> addStructure(files[i]) |>
 addRepresentation("cartoon", param = list(color = cols[i]))
}
/Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//1E4V_A.pdb 
/Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//1E4Y_A.pdb 
/Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//3HPR_A.pdb 
/Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//3X2S_A.pdb 
/Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//4K46_A.pdb 
/Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//4NP6_A.pdb 
/Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//4X8H_A.pdb 
/Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//4X8M_A.pdb 
/Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//5EJE_A.pdb 
/Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//6HAM_A.pdb 
/Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//6HAP_A.pdb 
/Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//6RZE_A.pdb 
/Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//6S36_A.pdb 
/Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//8BQF_A.pdb 
/Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//8PVW_A.pdb 
/Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//8Q2B_A.pdb 
/Users/barry/Desktop/courses/BIMM143/class10/pdbs/split_chain//8RJ9_A.pdb 
x

How about a multi-model PDB

# NMR ras structure
id <- "1CRR"

NGLVieweR(id) |>
  addRepresentation("cartoon")
nmr <- read.pdb(id, multi = T)
  Note: Accessing on-line PDB file
nmr

 Call:  read.pdb(file = id, multi = T)

   Total Models#: 1
     Total Atoms#: 0,  XYZs#: 0  Chains#: 0  (values: )

     Protein Atoms#: 0  (residues/Calpha atoms#: 0)
     Nucleic acid Atoms#: 0  (residues/phosphate atoms#: 0)

     Non-protein/nucleic Atoms#: 0  (residues: 0)
     Non-protein/nucleic resid values: [ none ]

+ attr: atom, xyz, calpha, call
nmr <- read.pdb("1crr", multi = F)
  Note: Accessing on-line PDB file
Warning in get.pdb(file, path = tempdir(), verbose = FALSE):
/var/folders/jd/wjwf0lcj0kd0tch_70sd1l4w0000gn/T//RtmpC2zZLw/1crr.pdb exists.
Skipping download
nmr

 Call:  read.pdb(file = "1crr", multi = F)

   Total Models#: 1
     Total Atoms#: 0,  XYZs#: 0  Chains#: 0  (values: )

     Protein Atoms#: 0  (residues/Calpha atoms#: 0)
     Nucleic acid Atoms#: 0  (residues/phosphate atoms#: 0)

     Non-protein/nucleic Atoms#: 0  (residues: 0)
     Non-protein/nucleic resid values: [ none ]

+ attr: atom, xyz, calpha, call
NGLVieweR("pca.pdb") |>
  addRepresentation("cartoon")
p <- read.pdb("pca.pdb", multi = T)
NGLVieweR(pdb2ngl(p), format="pdb") |>
  addRepresentation("cartoon")
data <- "pca.pdb"
data <- paste(readLines(data), collapse = "\n")
NGLVieweR(data, format="pdb") |>
  addRepresentation("cartoon")